package models

import (
	"math/rand"
	"strconv"
	"strings"
	"time"
	"xxp_api/utils"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/medivhzhan/weapp"
)

//获取用户绑定信息
func GetWechatInfo(code, nickname, headimgurl, invitation string) Response {

	ormer := orm.NewOrm()
	ormer.Using("default") // 默认使用 default，你可以指定为其他数据库
	var ret Response

	appid := beego.AppConfig.String("appid")
	secret := beego.AppConfig.String("secret")
	res, err := weapp.Login(appid, secret, code)
	beego.Debug(res)
	if err != nil {
		beego.Debug("获取用户信息出错：", res, err)
		ret.Code = 100100
		ret.Msg = "获取openid出错"
		return ret
	}

	//查询当前openid是否已存在
	var user Xxp_kol

	err = ormer.Raw("SELECT * FROM `xxp_kol` WHERE openid = ? ", res.OpenID).QueryRow(&user)
	if err == nil {
		//更新最后登录时间
		ormer.Raw("UPDATE `xxp_kol` SET modified = ? WHERE id = ?", time.Now().Unix(), user.Id).Exec()
		ret.Msg = "登录成功"

		ret.Data = user
		return ret
	}
	//新用户注册

	var pid int64
	nowtime := time.Now().Unix()
	if invitation != "" {
		ormer.Raw("SELECT id FROM `xxp_kol` WHERE invitation_code = ? ", invitation).QueryRow(&pid)
	}
	var newuser Xxp_kol
	newuser.Head_img = headimgurl
	newuser.Status = 1
	newuser.Nickname = nickname
	newuser.Openid = res.OpenID
	newuser.Pid = int(pid)
	newuser.InvitationCode = GetInvitationCode(1)
	newuser.Created = nowtime
	newuser.Modified = nowtime

	var ormer1 = orm.NewOrm()
	ormer1.Begin()
	_, err3 := ormer1.Insert(&newuser)
	if err3 != nil {
		ret.Code = 100110
		ret.Msg = "账号创建失败"
		ormer1.Rollback()
		return ret
	}
	//初始kol余额
	var userassets Xxp_kol_assets
	userassets.Uid = newuser.Id
	userassets.Modified = nowtime
	userassets.Quota = 2000.0
	_, err3 = ormer1.Insert(&userassets)
	if err3 != nil {
		ret.Code = 100111
		ret.Msg = "账号余额初始化失败"
		ormer1.Rollback()
		return ret
	}
	//初始化用户店铺
	var shop Xxp_shop
	shop.Kol_id = newuser.Id
	shop.Status = 1
	shop.Name = nickname + "的店铺"
	shop.Head_img = headimgurl
	shop.Created = nowtime
	shop.Modified = nowtime
	shop.Shop_str = GetShopShareCode()
	_, err3 = ormer1.Insert(&shop)
	if err3 != nil {
		ret.Code = 100112
		ret.Msg = "账号店铺初始化失败"
		ormer1.Rollback()
		return ret
	}
	ormer1.Commit()

	ret.Data = newuser
	ret.Msg = "登录成功"
	return ret
}

//GetInvitationCode 获取一个新的邀请码
func GetInvitationCode(types int) string {

	//var t = []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "d", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
	var t = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
	var key string
	result := 0
	for result == 0 {
		rand.Seed(time.Now().UnixNano()) //利用当前时间的UNIX时间戳初始化rand包
		for i := 0; i < 6; i++ {
			x := rand.Intn(len(t))
			if i == 0 {
				key = t[x]
			} else {
				key = key + t[x]
			}

			t = append(t[:x], t[x+1:]...)
		}
		if types == 1 {
			//判断当前邀请码是否存在于数据库
			var user Xxp_kol
			err := ormer.Raw("SELECT * FROM xxp_kol WHERE invitation_code = ?", key).QueryRow(&user)
			if err != nil {
				result = 1 //不存在直接使用
			} else {
				result = 0
			}
		} else {
			result = 1
		}

	}

	return key
}

//获取一个新的分享码
func GetShopShareCode() string {

	var t = []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
	//var t = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
	var key string
	result := 0
	for result == 0 {
		rand.Seed(time.Now().UnixNano()) //利用当前时间的UNIX时间戳初始化rand包
		for i := 0; i < 8; i++ {
			x := rand.Intn(len(t))
			if i == 0 {
				key = t[x]
			} else {
				key = key + t[x]
			}

			t = append(t[:x], t[x+1:]...)
		}

		//判断当前邀请码是否存在于数据库
		var user Xxp_shop
		err := ormer.Raw("SELECT * FROM xxp_shop WHERE shop_str = ?", key).QueryRow(&user)
		if err != nil {
			result = 1 //不存在直接使用
		} else {
			result = 0
		}
	}

	return key
}

//设置用户身份证号码
func Setidcard(uid int, name, idcard string) Response {
	var res Response
	var user Xxp_kol
	user.Id = int64(uid)
	ormer.Read(&user)
	user.Id_card = idcard
	user.Name = name
	_, err := ormer.Update(&user)
	if err != nil {
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
	}
	return res
}

type myOrder struct {
	Daymoney float64
	Dayorder int
	Allmoney float64
	Allorder int
}
type myOrder1 struct {
	Order     [3]myOrder
	Share     string
	Shop_name string
}
type order struct {
	Money  float64
	Counts int
	Types  int
}

//我的页面
func KolMy(uid int) Response {
	share_url := beego.AppConfig.String("h5_share")
	var res Response
	var day, all []order
	//计算当前日期零点时间
	t, _ := time.Parse("2006-01-02", time.Now().Format("2006-01-02"))
	nowtime := t.Unix()
	sql := "SELECT SUM(o.order_money) as money,COUNT(o.id) as counts,goods_type as types FROM `xxp_orders`o ,xxp_shop shop where shop.id = o.shop_id AND shop.kol_id = ? AND o.status = 10"
	ormer.Raw(sql+" GROUP BY o.goods_type", uid).QueryRows(&all)
	ormer.Raw(sql+" AND o.created > ? "+" GROUP BY o.goods_type", uid, nowtime).QueryRows(&day)
	var data [3]myOrder
	for _, v := range day {
		data[v.Types-1].Daymoney = utils.Round(v.Money, 2)
		data[v.Types-1].Dayorder = v.Counts
	}
	for _, v := range all {
		data[v.Types-1].Allmoney = utils.Round(v.Money, 2)
		data[v.Types-1].Allorder = v.Counts
	}
	var or myOrder1
	shop := ShopGetDetail(uid)
	or.Share = share_url + "/index?sid=" + strconv.Itoa(int(shop.Id))
	or.Shop_name = shop.Name
	or.Order = data
	res.Data = or
	return res
}

type Balance struct {
	Balance  float64 //可提现余额
	Order    float64 //成单金额
	Rebate   float64 //返利金额
	Frozen   float64 //冻结金额
	Bond     float64 //保证金
	AllOrder float64 //总成单金额

}

//我的余额
func KolBalance(uid int) Response {
	var res Response
	var assets Xxp_kol_assets
	var data Balance
	ormer.Raw("SELECT * FROM `xxp_kol_assets` where uid = ?", uid).QueryRow(&assets)
	data.Balance = utils.Round(assets.Balance, 2)
	data.Bond = utils.Round(assets.Bond, 2)
	data.Frozen = utils.Round(assets.Frozen, 2)
	res.Data = data
	return res
}

//我的额度和手续费
func KolQuota(uid int) Response {
	var res Response
	var assets Xxp_kol_assets
	//计算手续费
	var fee float64
	ormer.Raw("select fee from xxp_fee where id =1 ").QueryRow(&fee)
	ormer.Raw("SELECT * FROM `xxp_kol_assets` where uid = ?", uid).QueryRow(&assets)
	res.Data = map[string]float64{
		"Quota": utils.Round(assets.Quota, 2),
		"Fee":   utils.Round(fee, 2),
	}
	return res
}

//获取短信验证码
func KolSms(uid int) Response {
	var res Response
	code := GetInvitationCode(2)
	var user Xxp_kol
	user.Id = int64(uid)
	ormer.Read(&user)
	beego.Info(user)
	err := utils.SMSXsend(user.Mobile, code)
	err1 := strings.LastIndex(err, "OK")
	if err1 == -1 {
		beego.Debug(err)
		res.Code = 100300
		res.Msg = "验证码获取错误"
		return res
	}
	//保存验证码
	ormer.Raw("INSERT INTO `xxp_smscode`(`uid`, `mobile`, `code`, `codetime`) VALUES (?,?,?,?) ", uid, user.Mobile, code, time.Now().Unix()+120).Exec()
	return res
}

//提现接口
func KolWithdraw(uid int, amount float64, code, card, name, bank, branch string) (res Response) {
	//验证码检验
	var code0 Xxp_smscode
	ormer.Raw("SELECT * FROM `xxp_smscode` WHERE uid=? AND code = ? ", uid, code).QueryRow(&code0)
	if code0.Id <= 0 {
		res.Code = 100400
		res.Msg = "验证码错误"
		return
	} else if code0.Codetime < time.Now().Unix() {
		res.Code = 100410
		res.Msg = "验证码已过期"
		return
	}
	//比对用户可提现余额是否充足
	var assets0 Xxp_kol_assets
	ormer.Raw("SELECT * FROM `xxp_kol_assets` WHERE uid = ?", uid).QueryRow(&assets0)
	if assets0.Balance < amount {
		res.Code = 100420
		res.Msg = "余额不足"
		return
	}
	//计算手续费
	var fee float64
	ormer.Raw("select fee from xxp_fee where id =1 ").QueryRow(&fee)
	var quota float64 //本次扣除免费额度
	var Fee float64   //本次收取手续费
	if amount > assets0.Quota {
		quota = assets0.Quota
		Fee = utils.Round((amount-assets0.Quota)*fee*0.01, 2)
	} else {
		quota = amount
		Fee = 0
	}
	//准备提现操作
	var ormer1 = orm.NewOrm()
	var nowtime = time.Now().Unix()
	ormer1.Begin()
	//加锁
	_, err := ormer1.Raw("SELECT * FROM `xxp_kol_assets` WHERE id = ? FOR UPDATE", assets0.Id).Exec()
	if err != nil {
		ormer1.Rollback()
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
		return
	}
	//更改余额和冻结
	_, err = ormer1.Raw("UPDATE `xxp_kol_assets` SET balance=balance-?,`frozen`=frozen + ?,`quota`=quota- ?,`modified`=? WHERE id=?", amount, amount, quota, nowtime, assets0.Id).Exec()
	if err != nil {
		ormer1.Rollback()
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
		return
	}
	//增加账单log
	alog := new(Xxp_kol_assets_log)
	alog.Created = nowtime
	alog.Money = amount
	alog.Status = 0
	alog.Transfer = 2
	alog.Types = 2
	alog.Uid = int64(uid)
	_, err = ormer1.Insert(alog)

	//插入提现记录
	_, err = ormer1.Raw("INSERT INTO `xxp_withdraw`(`uid`, `aid`, `name`, `bank`, `branch`, `card`, `withdrawal_amount`, `arrival_amount`, `status`, `created`, `modified`) VALUES (?,?,?,?,?,?,?,?,?,?,?)", uid, alog.Id, name, bank, branch, card, amount, amount-Fee, 5, nowtime, nowtime).Exec()
	if err != nil {
		ormer1.Rollback()
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
		return
	}

	//判断用户余额是否大于0
	var balace float64
	err = ormer1.Raw("SELECT balance FROM `xxp_kol_assets` WHERE id = ?", assets0.Id).QueryRow(&balace)
	if err != nil || balace < 0 {
		ormer1.Rollback()
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
		return
	}
	ormer1.Commit()
	res.Msg = "提现请求成功"
	return
}

type Income struct {
	Time   int64
	In     int     //1收入，0支出
	Types  int     //1已提现，2未通过，3审核中，4返利结算
	Amount float64 //金额

}

func KolBalanceDetail(uid, types, keystart int) (res Response) {
	var lists List
	var log []Xxp_kol_assets_log
	var income []Income
	sql := "SELECT * FROM `xxp_kol_assets_log` WHERE uid=? "
	switch types {
	case 0:
		sql += "  "
	case 1:
		sql += "AND types=2 AND status = 1 "
	case 2:
		sql += "AND types=2 AND status = 2 "
	case 3:
		sql += "AND types=2 AND status = 0 "
	case 4:
		sql += "AND types=3 AND status = 1 "
	case 5:
		sql += "AND types=3 AND status = 0 "
	case 6:
		sql += "AND types=3 AND status = 2 "
	}
	ormer.Raw(sql+"  order by created DESC LIMIT ?,10", uid, 10*keystart).QueryRows(&log)
	keystart = keystart + 1
	if len(log) <= 0 {
		lists.List = []string{}
	} else {
		for _, v := range log {
			var in Income
			in.Amount = v.Money
			in.Time = v.Created
			if types == 0 {
				if v.Types == 2 {
					switch v.Status {
					case 0:
						in.Types = 3
					case 1:
						in.Types = 1
					case 2:
						in.Types = 2
					}
				} else {
					switch v.Status {
					case 0:
						in.Types = 5
					case 1:
						in.Types = 4
					case 2:
						in.Types = 6
					}
				}
			} else {
				in.Types = types
			}

			if v.Types == 2 {
				in.In = 0
			} else {
				in.In = 0
			}
			income = append(income, in)
		}
		lists.List = income
	}
	//判断是否有下一页
	var a []Xxp_kol_assets_log
	n, _ := ormer.Raw(sql+" order by created DESC LIMIT ?,10", uid, 10*keystart).QueryRows(&a)
	if n > 0 {
		lists.Hasnext = 1
	}
	lists.Keystart = keystart
	res.Data = lists
	return
}

//获取短信验证码
func KolBindPhone(uid int, phone string) Response {
	var res Response
	code := GetInvitationCode(2)
	err := utils.SMSXsend(phone, code)
	err1 := strings.LastIndex(err, "OK")
	if err1 == -1 {
		beego.Debug(err)
		res.Code = 100300
		res.Msg = "验证码获取错误"
		return res
	}
	//保存验证码
	ormer.Raw("INSERT INTO `xxp_smscode`(`uid`, `mobile`, `code`, `codetime`) VALUES (?,?,?,?) ", uid, phone, code, time.Now().Unix()+120).Exec()
	res.Msg = "获取验证码成功"
	return res
}

//保存手机号码
func KolSavePhone(uid int, phone, code, invitation string) (res Response) {

	//验证码检验
	var code0 Xxp_smscode
	ormer.Raw("SELECT * FROM `xxp_smscode` WHERE uid=? AND code = ? ", uid, code).QueryRow(&code0)
	if code0.Id <= 0 {
		res.Code = 100400
		res.Msg = "验证码错误"
		return
	} else if code0.Codetime < time.Now().Unix() {
		res.Code = 100410
		res.Msg = "验证码已过期"
		return
	} else if code0.Mobile != phone {
		res.Code = 100420
		res.Msg = "手机号码错误"
		return
	}
	var pid int64
	if invitation != "" {
		ormer.Raw("SELECT id FROM `xxp_kol` WHERE invitation_code = ? ", invitation).QueryRow(&pid)
	}
	//保存验证码
	_, err := ormer.Raw("UPDATE `xxp_kol` SET `mobile`=?,pid=? WHERE id=?", phone, pid, uid).Exec()
	if err != nil {
		beego.Debug(err.Error())
		res.Code = ERRCODE_DATABASE_ERROR
		res.Msg = "数据出错"
		return
	}
	res.Msg = "保存成功"
	return res
}
